package com.surekam.core.dynamicproperties;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Map;

import org.apache.commons.beanutils.ConvertUtilsBean;

/**
 * 用法呢？ Java代码
 * 
 * @interface Foo { int id(); String name() default ""; Gender sex(); }
 * 
 *            Map<String, String> map = ...; Foo foo = PropertyConverter.to(Foo.class).from(map); foo.id(); foo.name();
 * 
 *            这里面，对annotation的用法比较特别。不过不这么做，java也不提供一个简单并且类型安全的指定缺省值的方法。当然，
 *            如果你凑巧不需要缺省值，那么也不用annotation，直接用interface就好
 * @author wwei
 * 
 * @param <T>
 */
public final class PropertyConverter<T> {

	private final Class<T> targetType;

	private PropertyConverter(Class<T> targetType) {
		this.targetType = targetType;
	}

	public static <T> PropertyConverter<T> to(Class<T> targetType) {
		return new PropertyConverter<T>(targetType);
	}

	@SuppressWarnings("unchecked")
	public T form(final Map<String, String> map) {
		return (T) Proxy.newProxyInstance(targetType.getClassLoader(), new Class[] { targetType },
				new InvocationHandler() {

					@Override
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
						String value = map.get(method.getName());
						if (value == null) {
							Object defaultValue = method.getDefaultValue();
							if (defaultValue == null) {
								throw new Throwable("aa");
							}
							return defaultValue;
						}
						ConvertUtilsBean cb = new ConvertUtilsBean();
						return cb.convert(value, method.getReturnType());
					}

				});
	}
}
